import { CanActivate, ExecutionContext, Injectable } from "@nestjs/common";
import { Reflector } from '@nestjs/core'
import { Request } from 'express'
import 'reflect-metadata'

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private reflector: Reflector) {

  }
  /**
   * 通过返回值决定路由处理函数是否执行
   * @param context 执行上下文 可以获取请求对象和响应对象
   */
  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get('roles', context.getHandler()) // 从路由处理函数上获取 roles 元数据
    // const roles = Reflect.getMetadata('roles', context.getHandler()) // 从路由处理函数上获取 roles 元数据 与上面等价
    console.log('roles: ', roles)
    if (!roles) { 
      return true // 没有为此路由函数设置角色 意味此路由处理函数可以被任何人访问 没有权限
    }
    const request = context.switchToHttp().getRequest<Request>() // 获取请求对象
    const user = {id: 1, name: 'nick', role: request.query.role} // 假设从会话中取
    return matchRoles(roles, user.role)
  }
  
}

/**
 * 判断权限数组中是否包含该权限
 */
function matchRoles(roles, role) {
  return roles.includes(role)
}

/**
ExecutionContext 是继承 ArgumentsHost 的类
拥有2个额外的方法
getClass() 获取路由处理函数所在的类
getHandler() 获取路由处理函数
 */
